#pragma once

#include <iostream>
#include <string>
#include <sqlite3.h>
using namespace std;

class SqliteHelper
{
    // void* : 是设置的在回调时传入的 arg 参数
    // int：一行中数据的列数
    // char**：存储一行数据的字符指针数组
    // char**：每一列的字段名称
    // 回调函数也有返回值(返回值只有为SQLITE_OK才表示成功)
    typedef int (*SqliteCallback)(void *, int, char **, char **);

public:
    SqliteHelper(const string &dbfile)
        : _dbfile(dbfile), _sq(nullptr)
    {
    }

    // #define SQLITE_OK           0   /* Successful result */
    bool open(int safe_level = SQLITE_OPEN_FULLMUTEX)
    {
        int ret = sqlite3_open_v2(_dbfile.c_str(), &_sq,
                                  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | safe_level, nullptr);
        if (ret != SQLITE_OK)
        {
            cerr << "创建/打开SQLITE数据库失败: " << sqlite3_errmsg(_sq) << endl;
            return false;
        }
        return true;
    }
    bool exec(const string &sql_statement, const SqliteCallback &callback, void *arg)
    {
        int ret = sqlite3_exec(_sq, sql_statement.c_str(), callback, arg, nullptr);
        if (ret != SQLITE_OK)
        {
            cerr << sql_statement << " 执行该语句失败 " << endl;
            return false;
        }
        return true;
    }
    void close()
    {
        sqlite3_close_v2(_sq);
    }

private:
    string _dbfile;
    sqlite3 *_sq; // 数据库句柄
};